////
/// @group snackbar
////

@use "sass:map";
@use "../utils";
@use "../border-radius";
@use "../spacing";
@use "../box-shadows";
@use "../button/button";
@use "../theme/a11y";
@use "../theme/theme";
@use "../icon/icon";
@use "../media-queries/media-queries";
@use "../interaction/interaction";
@use "../typography/typography";
@use "../transition/transition";

/// Set to `true` to disable all the styles.
/// @type Boolean
$disable-everything: false !default;

/// Set to `true` if the `position: absolute` styles are not required where a
/// `Snackbar` is rendered within another `position: relative` container.
///
/// @type Boolean
$disable-absolute: false !default;

/// Set to `true` to disable the styles for a `Snackbar` positioned at the top
/// of the page/container.
/// @type Boolean
$disable-top: false !default;

/// Set to `true` to disable the styles for a `Snackbar` positioned at the
/// bottom of the page/container.
/// @type Boolean
$disable-bottom: false !default;

/// Set to `true` to disable the styles for a `Snackbar` positioned at the
/// top-right of the page/container.
/// @type Boolean
$disable-top-right: $disable-top !default;

/// Set to `true` to disable the styles for a `Snackbar` positioned at the
/// top-left of the page/container.
/// @type Boolean
$disable-top-left: $disable-top !default;

/// Set to `true` to disable the styles for a `Snackbar` positioned at the
/// bottom-left of the page/container.
/// @type Boolean
$disable-bottom-left: $disable-bottom !default;

/// Set to `true` to disable the styles for a `Snackbar` positioned at the
/// bottom-right of the page/container.
/// @type Boolean
$disable-bottom-right: $disable-bottom !default;

/// Set to `true` to disable the `ToastCloseButton` styles.
/// @type Boolean
$disable-close-button: false !default;

/// Set to `true` to disable the `ToastActionButton` styles.
/// @type Boolean
$disable-action-button: false !default;

/// Set to `true` to disable the stacked `Snackbar` styles.
/// @type Boolean
$disable-stacked: false !default;

/// The default `align-items` for a `Snackbar`.
/// @type String
$default-align-items: center !default;

/// The default `gap` for a `Snackbar`.
/// @type Number
$gap: spacing.get-var(md) !default;

/// The default `gap` for a `Toast`.
/// @type Number
$toast-gap: spacing.get-var(md) !default;

/// The default `gap` for a stacked `Toast`.
/// @type Number
$toast-gap-stacked: spacing.get-var(sm) !default;

/// The default `gap` for a toast that has both a `ToastActionButton` and
/// `ToastCloseButton`.
/// @type Number
$toast-gap-both-buttons: spacing.get-var(xs) !default;

/// The viewport margin to apply to all `Toast` rendered within the `Snackbar`.
/// @type Number
$margin: spacing.get-var(md) !default;

/// A number between 0-24 representing the box-shadow elevation for a `Toast`.
/// @type Number
$elevation: 6 !default;

/// The default border-radius for a `Toast`.
/// @type Number
$border-radius: border-radius.get-var(xs) !default;

/// The default vertical padding for a `Toast`.
/// @type Number
$vertical-padding: calc(spacing.get-var(sm) * 1.5) !default;

/// The default horizontal padding for a `Toast`.
/// @type Number
$horizontal-padding: spacing.get-var(md) !default;

/// The default horizontal padding for a `Toast` that has an
/// `ToastActionButton`.
/// @type Number
$action-horizontal-padding: spacing.get-var(sm) !default;

/// The default horizontal padding for a `Toast` that has an
/// `ToastCloseButton`.
/// @type Number
$close-button-horizontal-padding: spacing.get-var(none) !default;

/// The min-height for a `Toast`.
/// @type Number
$min-height: 3rem !default;

/// The min-width for a `Toast` when the viewport is tablet or above.
/// @type Number
$min-width: 21.5rem !default;

/// The max-width for a `Toast`.
/// @type Number
$max-width: 35.5rem !default;

/// The default `z-index` for a `Toast`.
/// @type Number
$z-index: utils.$temporary-element-z-index + 10 !default;

/// The default `Toast` typography styles.
/// @type Map
$typography: map.merge(
  typography.$base-font-styles,
  typography.$subtitle-2-styles
) !default;

/// The background-color to use in the light theme.
/// @type Color
$light-theme-background-color: #323232 !default;

/// The text color to use in the light theme.
/// @type Color
$light-theme-color: a11y.contrast-color($light-theme-background-color) !default;

/// The background-color to use in the dark theme.
/// @type Color
$dark-theme-background-color: if(
  theme.$disable-dark-elevation,
  $light-theme-background-color,
  map.get(theme.$dark-elevation-colors, $elevation)
) !default;

/// The text color to use in the dark theme.
/// @type Color
$dark-theme-color: a11y.contrast-color($dark-theme-background-color) !default;

/// The default background-color for a `Toast`.
/// @type Color
$background-color: theme.get-default-color(
  $light-theme-background-color,
  $dark-theme-background-color
) !default;

/// The default text color for a `Toast`.
/// @type Color
$color: theme.get-default-color($light-theme-color, $dark-theme-color) !default;

/// The available configurable css variables and mostly used internally for the
/// `get-var`, `set-var`, and `use-var` utils.
/// @type List
$variables: (background-color, color, offset);

/// @param {String} name - The supported variable name
/// @param {any} fallback [null] - An optional fallback value
/// @returns {String} a `var()` statement
@function get-var($name, $fallback: null) {
  $var: utils.get-var-name($variables, $name, "snackbar");
  @if $fallback {
    @return var(#{$var}, #{$fallback});
  }

  @return var(#{$var});
}

/// @param {String} name - The supported variable name
/// @param {any} value - The value to set the variable to. Supports `null` which
/// will just be a no-op.
@mixin set-var($name, $value) {
  @if $value {
    #{utils.get-var-name($variables, $name, "snackbar")}: #{$value};
  }
}

/// @param {String} property - The css property to apply the variable to
/// @param {String} name [$property] - The supported variable name
/// @param {any} fallback [null] - An optional fallback value if the variable
/// has not been set
@mixin use-var($property, $name: $property, $fallback: null) {
  #{$property}: get-var($name, $fallback);
}

/// Conditionally applies the css variables based on feature flags
@mixin variables {
  @if not $disable-everything {
    @include set-var(background-color, $background-color);
    @include set-var(color, $color);
    @include set-var(offset, 0);
  }
}

/// Generates all the styles based on feature flags.
///
/// @param {Boolean} disable-layer [false] - Set this to `true` to disable the
/// layer behavior
@mixin styles($disable-layer: false) {
  @if not $disable-everything {
    @include utils.optional-layer(snackbar, $disable-layer) {
      .rmd-snackbar {
        align-items: $default-align-items;
        display: flex;
        flex-direction: column;
        gap: $gap;
        left: 0;
        margin: $margin;
        pointer-events: none;
        position: fixed;
        right: 0;
        z-index: $z-index;

        @if not $disable-absolute {
          &--absolute {
            position: absolute;
          }
        }

        @if not
          $disable-top or not
          $disable-top-left or not
          $disable-bottom-left
        {
          &--top {
            @include use-var(top, offset);
          }
        }

        @if not
          $disable-bottom or not
          $disable-bottom-left or not
          $disable-bottom-right
        {
          &--bottom {
            @include use-var(bottom, offset);
          }
        }

        @if not $disable-top-left or not $disable-bottom-left {
          &--start {
            align-items: flex-start;
          }
        }

        @if not $disable-top-right or not $disable-bottom-right {
          &--end {
            align-items: flex-end;
          }
        }
      }

      .rmd-toast {
        @include box-shadows.box-shadow($elevation, $disable-colors: true);
        @include utils.map-to-styles($typography);
        @include use-var(background-color);
        @include use-var(color);

        align-items: center;
        border-radius: $border-radius;
        display: flex;
        gap: $toast-gap;
        justify-content: space-between;
        max-width: $max-width;
        min-height: $min-height;
        padding-left: $horizontal-padding;
        padding-right: $horizontal-padding;
        pointer-events: auto;
        width: 100%;

        @include media-queries.tablet-media {
          min-width: $min-width;
          width: auto;
        }

        @if not $disable-action-button {
          &--action {
            padding-right: $action-horizontal-padding;

            @include utils.rtl {
              padding-left: $action-horizontal-padding;
              padding-right: $horizontal-padding;
            }
          }
        }

        @if not $disable-close-button {
          &--x {
            padding-right: $close-button-horizontal-padding;

            @include utils.rtl {
              padding-left: $close-button-horizontal-padding;
              padding-right: $horizontal-padding;
            }
          }

          @if not $disable-action-button {
            &--small-gap {
              gap: $toast-gap-both-buttons;
            }
          }
        }

        @if not $disable-stacked {
          &--stacked {
            display: grid;
            gap: $toast-gap-stacked;
            grid-template-columns: 1fr;
            padding-bottom: $vertical-padding;
            padding-top: $vertical-padding;
          }

          &--reordered {
            grid-template-columns: 1fr min-content;
            padding-top: 0;
          }
        }
      }

      .rmd-toast-content {
        flex: 1 1 auto;

        p {
          margin: 0;
        }

        &--v-padding {
          padding: $vertical-padding 0;
        }

        &--t-padding {
          padding-bottom: 0;
        }

        @if not $disable-action-button {
          &--action {
            padding-right: button.$text-horizontal-padding;

            @include utils.rtl {
              padding-left: button.$text-horizontal-padding;
              padding-right: 0;
            }
          }
        }

        @if not $disable-close-button and not $disable-action-button {
          &--gap {
            margin-right: $toast-gap;

            @include utils.rtl {
              margin-left: $toast-gap;
              margin-right: 0;
            }
          }
        }
      }

      @if not $disable-close-button {
        .rmd-toast-x {
          &--reordered {
            align-self: flex-start;
            order: 2;
          }
        }
      }

      @if not $disable-action-button {
        .rmd-toast-action {
          justify-self: flex-end;

          &--reordered {
            grid-column-end: span 2;
            margin-right: $action-horizontal-padding;
            order: 3;

            @include utils.rtl {
              margin-left: $action-horizontal-padding;
              margin-right: 0;
            }
          }
        }
      }
    }
  }
}
